/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bgu.sonar.util.ui.logs;

import bgu.sonar.util.async.AsyncTask;
import bgu.sonar.util.ui.UICallback;
import bgu.sonar.util.ui.dialogs.MonitoredPleaseWaitDialog;
import bgu.sonar.util.ui.mon.Monitor;
import bgu.sonar.util.ui.mon.SimpleMonitor;
import bgu.sonar.util.ui.round.FlatScrollbarUI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.io.File;
import java.io.IOException;
import javax.swing.JScrollBar;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.openide.util.Exceptions;

/**
 *
 * @author bennyl
 */
public class PaginatedTextViewer extends javax.swing.JPanel implements PageDocumentModel.PageDocumentCloseListener {

    private PageDocumentModel currentModel; //can be grep
    private PageDocumentModel originalModel = null;
    private RSyntaxTextArea textArea;
    private final RTextScrollPane scrollpane;
    private boolean updating = false;

    /** Creates new form PaginatedTextViewer */
    public PaginatedTextViewer() {
        initComponents();

        contentLocationPanel.removeAll();
        textArea = new RSyntaxTextArea();
        textArea.setEditable(false);
        textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_NONE);
        textArea.setAnimateBracketMatching(true);
        textArea.setAntiAliasingEnabled(true);
        textArea.setForeground(Color.white);
        textArea.setCaretColor(new Color(120, 120, 120));
        textArea.setCurrentLineHighlightColor(new Color(71, 71, 71));
        textArea.setBackground(new Color(51, 51, 51));

        scrollpane = new RTextScrollPane(textArea, false, new Color(200, 200, 200));
        scrollpane.setLineNumbersEnabled(true);
        scrollpane.setBorder(null);
        scrollpane.setVerticalScrollBarPolicy(scrollpane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollpane.setHorizontalScrollBarPolicy(scrollpane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollpane.setBorder(null);
        scrollpane.getGutter().setBorderColor(new Color(255, 153, 0));
        contentLocationPanel.add(scrollpane, BorderLayout.CENTER);

        scrollpane.setBackground(new Color(51, 51, 51));

        //change the ui of the scroll bar
        for (Component c : scrollpane.getComponents()) {
            if (c instanceof JScrollBar) {
                ((JScrollBar) c).setUI(new FlatScrollbarUI());
            }
        }
        scrollpane.updateUI();
    }

    public void setModel(PageDocumentModel model) {
        model.getListeners().add(this);
        this.currentModel = model;
        this.originalModel = model;
        grepText.setText("");
        documentNameLabel.setText(model.getDocumentName());
        updateToPage(model);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        documentNameLabel = new javax.swing.JLabel();
        jPanel5 = new javax.swing.JPanel();
        grepText = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        nextPageLink2 = new org.jdesktop.swingx.JXHyperlink();
        contentLocationPanel = new javax.swing.JPanel();
        loadingPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        previousPageLink = new org.jdesktop.swingx.JXHyperlink();
        paginationTextLabel = new javax.swing.JLabel();
        nextPageLink = new org.jdesktop.swingx.JXHyperlink();

        setBackground(new java.awt.Color(255, 255, 255));
        setLayout(new java.awt.GridBagLayout());

        jPanel1.setBackground(new java.awt.Color(102, 102, 102));
        jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 10));

        documentNameLabel.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        documentNameLabel.setForeground(new java.awt.Color(240, 240, 240));
        org.openide.awt.Mnemonics.setLocalizedText(documentNameLabel, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.documentNameLabel.text_1")); // NOI18N
        jPanel1.add(documentNameLabel);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        add(jPanel1, gridBagConstraints);

        jPanel5.setBackground(new java.awt.Color(102, 102, 102));
        jPanel5.setLayout(new java.awt.GridBagLayout());

        grepText.setText(org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.grepText.text_1")); // NOI18N
        grepText.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 0, new java.awt.Color(204, 204, 204)), javax.swing.BorderFactory.createMatteBorder(3, 2, 3, 2, new java.awt.Color(255, 255, 255))));
        grepText.setMargin(new java.awt.Insets(2, 3, 2, 2));
        grepText.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                grepTextActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 5, 0);
        jPanel5.add(grepText, gridBagConstraints);

        jPanel3.setBackground(new java.awt.Color(255, 204, 0));
        jPanel3.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(255, 153, 0)));
        jPanel3.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 4));

        nextPageLink2.setForeground(new java.awt.Color(51, 51, 51));
        org.openide.awt.Mnemonics.setLocalizedText(nextPageLink2, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.nextPageLink2.text_1")); // NOI18N
        nextPageLink2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextPageLink2ActionPerformed(evt);
            }
        });
        jPanel3.add(nextPageLink2);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 3);
        jPanel5.add(jPanel3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        add(jPanel5, gridBagConstraints);

        contentLocationPanel.setBackground(new java.awt.Color(51, 51, 51));
        contentLocationPanel.setLayout(new java.awt.BorderLayout());

        loadingPanel.setBackground(new java.awt.Color(51, 51, 51));
        loadingPanel.setLayout(new java.awt.GridBagLayout());

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/img/loading_1.gif"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.jLabel1.text_1")); // NOI18N
        loadingPanel.add(jLabel1, new java.awt.GridBagConstraints());

        contentLocationPanel.add(loadingPanel, java.awt.BorderLayout.CENTER);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(contentLocationPanel, gridBagConstraints);

        jPanel2.setBackground(new java.awt.Color(102, 102, 102));

        previousPageLink.setForeground(new java.awt.Color(252, 172, 62));
        org.openide.awt.Mnemonics.setLocalizedText(previousPageLink, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.previousPageLink.text_1")); // NOI18N
        previousPageLink.setClickedColor(new java.awt.Color(252, 172, 62));
        previousPageLink.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        previousPageLink.setUnclickedColor(new java.awt.Color(252, 172, 62));
        previousPageLink.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                previousPageLinkActionPerformed(evt);
            }
        });
        jPanel2.add(previousPageLink);

        paginationTextLabel.setForeground(new java.awt.Color(255, 204, 0));
        org.openide.awt.Mnemonics.setLocalizedText(paginationTextLabel, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.paginationTextLabel.text_1")); // NOI18N
        jPanel2.add(paginationTextLabel);

        nextPageLink.setForeground(new java.awt.Color(252, 172, 62));
        org.openide.awt.Mnemonics.setLocalizedText(nextPageLink, org.openide.util.NbBundle.getMessage(PaginatedTextViewer.class, "PaginatedTextViewer.nextPageLink.text_1")); // NOI18N
        nextPageLink.setClickedColor(new java.awt.Color(252, 172, 62));
        nextPageLink.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        nextPageLink.setUnclickedColor(new java.awt.Color(252, 172, 62));
        nextPageLink.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextPageLinkActionPerformed(evt);
            }
        });
        jPanel2.add(nextPageLink);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        add(jPanel2, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

    private void grepTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_grepTextActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_grepTextActionPerformed

    private void nextPageLinkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageLinkActionPerformed
        if (currentModel.getCurrentPageNumber() + 1 < currentModel.getNumberOfPages()) {
            currentModel.gotoPageNumber(currentModel.getCurrentPageNumber() + 1);
            updateToPage(currentModel);
        }
    }//GEN-LAST:event_nextPageLinkActionPerformed

    private void previousPageLinkActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previousPageLinkActionPerformed
        if (currentModel.getCurrentPageNumber() - 1 >= 0) {
            currentModel.gotoPageNumber(currentModel.getCurrentPageNumber() - 1);
            updateToPage(currentModel);
        }
    }//GEN-LAST:event_previousPageLinkActionPerformed

    private void nextPageLink2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageLink2ActionPerformed
        if (grepText.getText().isEmpty()) {
            try {
                if (currentModel != originalModel) {
                    currentModel.close();
                }
                currentModel.getPath().delete();
                currentModel = originalModel;
                updateToPage(currentModel);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        } else {

            final Monitor mon = new SimpleMonitor("Grepping: " + grepText.getText());
            new AsyncTask() {
                @Override
                public Object call() throws Exception {
                    currentModel = originalModel.grep(new String[]{grepText.getText()}, new File(originalModel.getPathToStoreGrepFiles() + "/" + originalModel.getPath().getName() + ".grep"), mon);
                    mon.close();
                    return null;
                }
            }.executeInGlobalPool().addCallback(new UICallback() {
                @Override
                public void onFailedUI(Exception ex, boolean interrupted) {
                    Exceptions.printStackTrace(ex);
                }

                @Override
                public void onSuccessUI(Object res) {
                    updateToPage(currentModel);
                }
            });

            MonitoredPleaseWaitDialog.show(mon);
        }
    }//GEN-LAST:event_nextPageLink2ActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel contentLocationPanel;
    private javax.swing.JLabel documentNameLabel;
    private javax.swing.JTextField grepText;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel loadingPanel;
    private org.jdesktop.swingx.JXHyperlink nextPageLink;
    private org.jdesktop.swingx.JXHyperlink nextPageLink2;
    private javax.swing.JLabel paginationTextLabel;
    private org.jdesktop.swingx.JXHyperlink previousPageLink;
    // End of variables declaration//GEN-END:variables

    protected void updateToPage(final PageDocumentModel model) {
        if (!updating) {
            updating = true;
            paginationTextLabel.setText("[" + (model.getCurrentPageNumber() + 1) + "/" + model.getNumberOfPages() + "]");
            contentLocationPanel.removeAll();
            contentLocationPanel.add(loadingPanel, BorderLayout.CENTER);
            invalidate();
            revalidate();
            repaint();

            new AsyncTask<String>() {
                @Override
                public String call() throws Exception {
                    String res = model.getCurrentPageLines();
                    textArea.setText(res);
                    return res;
                }
            }.executeInGlobalPool().addCallback(new UICallback<String>() {
                @Override
                public void onFailedUI(Exception ex, boolean interrupted) {
                    Exceptions.printStackTrace(ex);
                    updating = false;
                }

                @Override
                public void onSuccessUI(String res) {
                    textArea.setCaretPosition(0);
                    contentLocationPanel.removeAll();
                    contentLocationPanel.add(scrollpane, BorderLayout.CENTER);
                    invalidate();
                    revalidate();
                    repaint();
                    updating = false;
                }
            });
        }

    }

    @Override
    public void onClose(PageDocumentModel page) {
        if (currentModel != page) {
            try {
                currentModel.close();
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }
        }
    }
}
